<?php

namespace App\Kuafu\Robot\Service;

use App\Kuafu\Base\Service\BaseService;
use App\Kuafu\Mqtt\Service\MqttQueueService;
use App\Kuafu\Pay\Model\PayStreamModel;
use App\Kuafu\Pay\Model\RefundStreamModel;
use App\Kuafu\Pay\Service\PayConfigService;
use App\Kuafu\Product\Enum\ProductCacheEnum;
use App\Kuafu\Product\Model\Product;
use App\Kuafu\Robot\Enum\RmsRobotCodeEnum;
use App\Kuafu\Shop\Enum\CameraCacheEnum;
use App\Kuafu\Shop\Enum\ShopCacheEnum;
use App\Kuafu\Shop\Jobs\SyncCameraJob;
use App\Kuafu\Shop\Model\CameraModel;
use App\Kuafu\Shop\Model\ShopProductStatus;
use App\Kuafu\Shop\Service\ShopCameraSyncService;
use App\Kuafu\Shop\Service\ShopService;
use App\Library\KfHttp\TigerCurl;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class RmsBotCommandService
{
    public string $command;

    public array $params;

    public array $sender;

    public function __construct(string $command, string $params = '', array $event = [])
    {
        $this->command = $command;
        $this->params  = explode(' ', $params);
        $this->event   = $event;
    }

    public function dealCommand()
    {
        $msgBot = new RmsBotSendService();

        switch ($this->command) {
            case RmsRobotCodeEnum::COMMAND_HELP:
                $returnMsg = $this->dealHelp();
                break;
            case RmsRobotCodeEnum::COMMAND_QUERY_PAY_NO:
                $returnMsg = $this->dealQueryPayNo();
                break;
            case RmsRobotCodeEnum::COMMAND_QUERY_THIRD_PAY_NO:
                $returnMsg = $this->dealQueryThirdPayNo();
                break;
            case RmsRobotCodeEnum::COMMAND_DOWNLOAD_OPEN_SHOP_CSV:
                $returnMsg = $this->downloadOpenShopCsv();
                break;
            case RmsRobotCodeEnum::COMMAND_CHANGE_SHOP_CAMERA:
                $returnMsg = $this->changeShopCamera();
                break;
            case RmsRobotCodeEnum::COMMAND_QUERY_BIZ_ID:
                $returnMsg = $this->queryBizId();
                break;
            case RmsRobotCodeEnum::COMMAND_UPDATE_YLK_SHOP_ID:
                $returnMsg = $this->updateYlkShopId();
                break;
            case RmsRobotCodeEnum::COMMAND_UPDATE_SHOP_PRODUCT_PRICE:
                $returnMsg = $this->updateShopProductPrice();
                break;
            default:
                return;
        }

        $msgBot->setGeneralMsg($returnMsg);
        $msgId = $this->getMessageId();
        $msgBot->replyMessage($msgId);
    }

    private function queryBizId(): string
    {
        $bizId = $this->params[0] ?? '';

        $res = [];

        PayStreamModel::query()->with('refundStreamRel')
                      ->where('bizId', $bizId)
                      ->where('payStatus', PayStreamModel::PAY_STATUS_1)
                      ->get()
                      ->each(function ($item, $payK) use (&$res) {
                          $payKK = $payK + 1;

                          $res[] = "===== 支付明细{$payKK} =====";
                          $res[] = "支付时间：" . $item->createdAt->toDateTimeString();
                          $res[] = '支付金额：' . bcdiv100($item->payPrice);
                          $res[] = '支付渠道：' . $item->payChannelName;
                          $res[] = '夸父支付单号：' . $item->payNo;
                          $res[] = '三方支付单号：' . $item->thirdPayNo;

                          $item->refundStreamRel->each(function ($refundStream, $k) use (&$res) {
                              if ($refundStream->refundStatus != RefundStreamModel::REFUND_STATUS_OK) {
                                  return;
                              }

                              $no    = $k + 1;
                              $res[] = "   === 退款明细{$no} ===";
                              $res[] = "   退款时间：" . $refundStream->createdAt->toDateTimeString();
                              $res[] = "   退款金额：" . bcdiv100($refundStream->refundPrice);
                              $res[] = "   夸父退款单号：" . $refundStream->refundNo;
                              $res[] = "   三方退款单号：" . $refundStream->thirdRefundNo;
                          });

                          $res[] = "\n";
                      });

        $returnStr = '';
        foreach ($res as $v) {
            $returnStr .= $v . "\n";
        }

        if (!$returnStr) {
            $returnStr = '未查询到相关支付明细';
        }

        return $returnStr;
    }

    public function getMessageId()
    {
        return $this->event['message']['message_id'] ?? '';
    }

    public function dealHelp()
    {
        $str = '';
        foreach (RmsRobotCodeEnum::COMMAND_LIST as $key => $item) {
            $str .= $key . ' ' . $item . PHP_EOL;
        }

        return $str;
    }

    private function dealQueryPayNo(): string
    {
        $payNo = $this->params[0];

        $payInfo = PayStreamModel::getDataByPayNo($payNo);

        if (empty($payInfo)) {
            $returnStr = '查不到该流水数据';
        } else {
            $returnStr = <<<STR
支付流水: {$payNo}
堂食订单: {$payInfo->orderId}
门店编号: {$payInfo->shop->shopCode}
门店名称: {$payInfo->shop->name}
STR;
        }
        return $returnStr;
    }

    private function dealQueryThirdPayNo(): string
    {
        $thirdPayNo = $this->params[0];

        $payInfo = PayStreamModel::suffix(null, PayStreamModel::SYS_TYPE_OPEN_SHOP_LEAGUE)
                                 ->where('thirdPayNo', $thirdPayNo)->first();

        if (empty($payInfo)) {
            $returnStr = '查不到该流水数据';
        } else {
            $payPrice      = bcdiv($payInfo->payPrice, 100, 2);
            $payStatusText = $payInfo->payStatus == PayStreamModel::PAY_STATUS_1 ? '已支付' : '未支付';
            $shopCode      = $payInfo->shop->shopCode ?? '';
            $shopName      = $payInfo->shop->name ?? '';
            $company       = (PayConfigService::COMPANY_TEXT[$payInfo->company] ?? '') . ' - ' . $payInfo->companyAccount;

            $returnStr = <<<STR
夸父支付流水: {$payInfo->payNo}
三方支付流水: {$payInfo->thirdPayNo}
业务单号: {$payInfo->bizId}
金额: {$payPrice}
支付渠道：{$payInfo->payChannelName}
公司信息: {$company}
支付状态: {$payStatusText}
门店编号: {$shopCode}
门店名称: {$shopName}
STR;
        }
        return $returnStr;
    }

    private function downloadOpenShopCsv(): string
    {
        $startDate = $this->params[0];
        $endDate   = $this->params[1] ?? '';
        $startTime = strtotime($startDate);
        if (!$startTime) {
            return '开始日期填写错误';
        }
        $endTime = strtotime($endDate) ?: 0;

        if ($startTime <= time() - 100 * 86400) {
            return '最多查询前100天的数据';
        }

        $params = [
            'startTime' => $startTime,
            'endTime'   => $endTime,
            'chat_id'   => $this->event['message']['chat_id'] ?? '',
        ];

        TigerCurl::getIns()->do('internal/openShop/downloadPayDetail', $params, 'POST');

        return '对账单生成中...';
    }

    private function changeShopCamera(): string
    {

        $sourceShopCode = (int)$this->params[0];
        $targetShopCode = (int)$this->params[1];

        $sourceShopInfo = ShopService::getShopInfoByCode($sourceShopCode);
        $targetShopInfo = ShopService::getShopInfoByCode($targetShopCode);

        if (empty($sourceShopInfo)) {
            return $sourceShopCode . " 原门店信息不存在";
        }

        if (empty($targetShopInfo)) {
            return $targetShopCode . " 目标门店不存在";
        }

//        if (empty($sourceShopInfo->ylkCameraSupplierId)) {
//            return $sourceShopCode . " 门店摄像头为空, 请勿操作";
//        }

        // 如果是悠络客更换悠络客的门店编号
        $ylkCameraSupplierId        = $targetShopInfo->cameraSupplierId;
        $targetShopInfo->cameraSupplierId = $sourceShopInfo->cameraSupplierId;
        $sourceShopInfo->cameraSupplierId = $ylkCameraSupplierId;
        // 更换设备的 shopId
        CameraModel::query()
                   ->where('deviceType', CameraModel::DEVICE_TYPE_CAMERA)
                   ->where('shopId', $sourceShopInfo->id)
                   ->update(
                       [
                           'shopId' => $targetShopInfo->id
                       ]
                   );
        $sourceShopInfo->save();
        $targetShopInfo->save();
        // 清空缓存
        Cache::forget(ShopCacheEnum::getShopInfo($targetShopInfo->id));
        Cache::forget(CameraCacheEnum::getCameraListCacheKey($targetShopInfo->id));
        return vsprintf("摄像头已经调整, 已经从 %s 调整至 %s, 数据缓存已清空.", [
            $sourceShopInfo->name,
            $targetShopInfo->name
        ]);
    }

    private function updateYlkShopId(): string
    {
        $sourceShopCode = (int)$this->params[0];

        $sourceShopInfo = ShopService::getShopInfoByCode($sourceShopCode);

        if (empty($sourceShopInfo)) {
            return $sourceShopCode . " 门店不存在";
        }

        ShopService::updateShopInfo(['shopCode' => $sourceShopCode], ['cameraSupplierId' => 0]);

//        dispatch(function () use ($sourceShopInfo) {
        Artisan::call('tools:import-ylk');

        // 更新这个门店的摄像头
        $server   = new ShopCameraSyncService();
        $shopInfo = ShopService::getShopInfo($sourceShopInfo->id);

        $count = $server->syncYlkCamera($sourceShopInfo->id, $shopInfo->cameraSupplierId);


        // 更新门店摄像头
        return '更新队列已触发, 请稍后查询';
    }

    private function updateShopProductPrice(): string
    {
        $sourceShopCode = (int)$this->params[0];
        $productId      = (int)$this->params[1];
        $priceYuan      = $this->params[2];

        $priceFen = (int)bcmul($priceYuan, 100);

        if (empty($sourceShopCode) || empty($productId) || empty($priceYuan)) {
            return '参数传入错误';
        }

        $showPlatform = 3;

        $sourceShopInfo = ShopService::getShopInfoByCode($sourceShopCode);

        if (empty($sourceShopInfo)) {
            return $sourceShopCode . " 原门店信息不存在";
        }

        $shopId  = $sourceShopInfo->id;
        $brandId = 1;

        // 校验门店菜单中是否存在这个菜
        $productInfo = Product::query()->where('id', $productId)->where('menuId', $sourceShopInfo->menuId)->first();

        if (empty($productInfo)) {
            return "该门店菜单不存在该商品";
        }

        $shopProductStatus = ShopProductStatus::insertOrGet(
            $shopId,
            $brandId,
            $productId,
            $priceFen,
            $showPlatform
        );

        $shopProductStatus->price        = $priceFen;
        $shopProductStatus->showPlatform = 3;
        $shopProductStatus->save();

        // 更新门店菜品缓存
        Cache::forget(ShopCacheEnum::getCustomShopProductStatus($shopId));
        Product::refreshGetMenuProductsPackageCustom($shopId);
        MqttQueueService::updateProductMenu([$shopId]);
        Cache::forget(ProductCacheEnum::getProductList($sourceShopInfo->menuId));

        return vsprintf("%s 门店的 %s 已更新至 %s 元, 已清空缓存, 已触发下拉菜单命令", [
            $sourceShopInfo->name,
            $productInfo->name,
            $priceYuan
        ]);
    }
}
